<template>
  <div>
    <div class="AIdialogue" :class="{ gCbxc5: deferred }"></div>
    <div class="xIlPaF">
      <div class="qfa7zW">
        <div class="g6rrRa"></div>
        <div class="wasolt" ref="scrollBottom">
          <div class="item" id="wasoltItem" v-for="(item, index) in list" :key="index" :class="{
            X05sUq: item.type == 'bot',
            MDCzlq: item.type == 'user',
            animation_fadeInUp: item.type == 'user',
            animation_fadeInBottom: item.type == 'bot',
          }">
            <div v-if="item.type == 'bot'" class="usable__root">
              <img src="https://img.wilmer.com.cn/admin/2024/4-24/%E6%98%9F.png" alt="" />
            </div>
            <div v-else class="usable__root">
              <img src="https://img.wilmer.com.cn/admin/2024/4-24/unnamed.png" alt="" />
            </div>

            <div v-if="item.type == 'bot' && index != 0 && item.animationState" class="cartoon">
              <LoadAnimation></LoadAnimation>
            </div>

            <vue-typed-js v-if="
              item.type == 'bot' &&
              !item.animationState &&
              item.content &&
              !item.isEnd
            " :strings="[item.content]" :showCursor="false" @onComplete="doSmth">
              <span class="typing"></span>
            </vue-typed-js>
            <span v-if="item.type == 'user'">{{ item.content }}</span>

            <vue-markdown v-if="list.length == 11 && item.isEnd" :source="item.content"></vue-markdown>
          </div>
          <!-- ai生成教案后显示内容 -->
          <div class="item X05sUq animation_fadeInBottom" style="margin-top: 20px" v-if="showButton">
            <div class="usable__root">
              <img src="https://img.wilmer.com.cn/admin/2024/4-24/%E6%98%9F.png" alt="" />
            </div>
            <div style="display: flex; flex-direction: column">
              <vue-typed-js :strings="[setOutGo]" :showCursor="false">
                <span class="typing"></span>
              </vue-typed-js>
              <button class="wds_1_104_2_ButtonCore__root tnnsET" @click="onTnnsET()">
                <span>前往管理页面</span>
              </button>
            </div>
          </div>
        </div>
        <div class="footerBtn" :class="{ gAF9KM: isAllow || videoLoding }">
          <el-input type="textarea" placeholder="请输入问题" v-model="textarea" resize="none" autosize
            @keydown.native="pushKeyword">
          </el-input>
          <button class="sendBox" :class="{ IqKDO6: !textarea, FtoDFp: isAllow || videoLoding }" @click="onclick()">
            <img src="https://img.wilmer.com.cn/admin/2024/4-24/%E5%8F%91%E9%80%81%402x.png" alt="" />
          </button>
          <!-- 遮罩层 -->
          <div class="Mrwb3p" v-if="isAllow"></div>
        </div>
      </div>
      <div class="w0Ne1v" :class="{ ssB8rM: offect }">
        <div style="transition: height 2s ease-in-out">
          <p :class="{ yy15WF: Delayed }" class="cnpA9f">您的教案档案</p>
          <p :class="{ yy15WF: Delayed }" class="g5WTUf">{{ title }}</p>
          <!-- 标签 -->
          <div class="iJQbS0 animation_fadeInUp" v-for="(item, index) in answerList" :key="index">
            <p class="lWRWg1">{{ item.content }}</p>
            <hr />
          </div>
        </div>
        <!-- 加载动画 -->
        <div class="TFPFEa" :class="{ h_Yv_y: !videoLoding }">
          <video width="120" height="120" muted autoplay="autoplay" loop="loop">
            <source src="https://img.wilmer.com.cn/admin/2024/4-27/sphere-small.c0680fb4.webm" type="video/webm" />
          </video>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import VueMarkdown from "vue-markdown";
import LoadAnimation from "@/components/LoadAnimation/LoadAnimation.vue";
import { TecherLessonPlan } from "@/api/question/question";
import { getToken } from "@/utils/auth";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import log from "@/views/monitor/job/log";
import Vue from "vue";
export default {
  components: {
    VueMarkdown,
    LoadAnimation,
  },
  data() {
    return {
      list: [
        {
          content: ``,
          type: "bot",
          animationState: false,
        },
      ], // 数据
      answerList: [], // 答案阅览
      textarea: "", // 用户输入的问题
      isAllow: true, // 是否允许用户输入问题
      offect: false, // 是否展示编辑预览
      Delayed: false, // 延时展示(答案预览)
      deferred: false, // 延时展示(背景)
      videoLoding: false,
      title: "",

      setOutGo: "一切准备就绪", // 出发去编辑页面
      showButton: false, // 显示按钮
    };
  },
  mounted() {
    setTimeout(() => {
      this.$set(
        this.list[0],
        "content",
        `您好，<br><br>我是AI教案生成助手，我可以为您快速生成教案。<br><br>** 首先，您给您的教案起个名字吧**`
      );
    }, 500);
  },
  methods: {
    onclick() {
      if (this.textarea != "") {
        this.list.push({
          content: this.textarea,
          type: "user",
        });
        this.videoLoding = true;
        this.textarea = "";
        this.isAllow = true;
      }



      // 用户能输入后，调用接口生成教案
      if (this.list.length == 10) {
        this.videoLoding = false;
        let obj = {
          lessonAdditional: this.list[9].content, // 补充信息
          lessonPlanMain: this.list[5].content, // 授课主题
          lessonPlanName: this.list[1].content, // 教案的名称
          lessonPlanObject: this.list[7].content, // 课程目标
          lessonPlanTo: this.list[3].content, // 授课对象
        };
        let that = this;
        setTimeout(function () {
          that.list.push({
            content: "",
            type: "bot",
            animationState: true,
            isEnd: true,
          });
        }, 600);
        //这个需要二次封装

        const controller = new AbortController();
        const signal = controller.signal;

        fetchEventSource(
          process.env.VUE_APP_BASE_API +
          `/TecherLessonPlan/TecherLessonPlan/kkk`,
          {
            method: "POST",
            signal: signal,
            headers: {
              "Content-Type": "application/json",
              Authorization: "Bearer " + getToken(), // 让每个请求携带自定义token 请根据实际情况自行修改
              Accept: "application/json, text/event-stream",
            },
            body: JSON.stringify(obj),
            onopen(response) {
              if (response.ok) {
                const contentType = response.headers.get("Content-Type");
                if (contentType.includes("text/event-stream")) {
                  console.log("Content-Type is text/event-stream");
                } else if (contentType.includes("application/json")) {
                  console.log("Content-Type is application/json");
                  let data = response.clone().text();
                  return data.then((r) => {
                    JSON.parse(r);
                    console.log(r);
                    Vue.prototype.$message.error(r);
                  });
                } else {
                  console.error("Unexpected Content-Type:", contentType);
                }
              }
            },
            onmessage(msg) {
              that.list[10].animationState = false;
              let detail = JSON.parse(msg.data);
              if (detail.event === "") {
                console.log(detail);
              } else if (detail.event === "close" || detail.event === "stop") {
                setTimeout(() => {
                  that.showButton = true
                }, 1000);
                controller.abort();
              }
              that.list[10].content += detail.content;
            },
            onerror(err) {
              throw err; // 或者throw改为其他
            },
          }
        );

        // // SSE 连接 类似 chatgpt 流数据
        // const eventSource = new EventSource(
        //   process.env.VUE_APP_BASE_API +
        //   `/TecherLessonPlan/TecherLessonPlan/kkk?lessonAdditional=${that.list[9].content}&lessonPlanMain=${that.list[5].content}&lessonPlanName=${that.list[1].content}&lessonPlanObject=${that.list[7].content}&lessonPlanTo=${that.list[3].content}`
        // );
        // eventSource.onmessage = (event) => {
        //   that.list[10].animationState = false;
        //   let detail = JSON.parse(event.data);
        //   if (
        //     detail.event === "stop"
        //   ) {
        //     eventSource.close(); // 终止 SSE
        //     return false;
        //   }
        //   that.list[10].content += detail.content;
        // };
      }
    },
    //
    // 滚动条自动滚动到底部
    scrollBottom() {
      this.$nextTick(() => {
        this.$refs.scrollBottom.scroll({
          top:
            this.$refs.scrollBottom.scrollHeight -
            this.$refs.scrollBottom.clientHeight,
          behavior: "smooth",
        });
      });
    },
    // 回车事件
    pushKeyword(event) {
      if (event.keyCode == 13) {
        event.preventDefault(); // 阻止浏览器默认换行操作
        this.onclick();
        event.target.blur(); // 回车失去焦点
      }
    },
    // 打字机效果
    typewriter(val, i) {
      let index = 0; // 将index声明在函数外部，以保持其状态
      let typedText = ""; // 同理，typedText也应该在函数外部维护

      const typeCharacter = () => {
        if (index < val.length) {
          typedText += val.charAt(index);
          index++;
          this.list[i].content = typedText;
          setTimeout(typeCharacter, 100); // 递归调用，持续打印
        }
      };

      typeCharacter(); // 初始调用
    },
    // 生成4-5秒的延时，模拟请求
    simulateRequest() {
      const randomDelay = Math.floor(Math.random() * 2) + 4; // 生成4-5之间的随机数
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(randomDelay);
        }, randomDelay * 1000);
      });
    },
    // 监听打字机动画结束
    doSmth() {
      let that = this;
      this.isAllow = false;
      if (this.list.length > 1) {
        this.title = this.list[1].content;
        if (this.list.length >= 5) {
          that.answerList.push({
            content: that.list[that.list.length - 2].content,
          });
        }
      }
      setTimeout(() => {
        this.videoLoding = false;
      }, 1000);
      if (this.list.length == 3) {
        this.offect = true;
      }
    },
    // 去编辑教案
    onTnnsET() {
      this.$router.push("/teacher/LessonPlanMrg");
    },
  },
  watch: {
    list: {
      handler(newVal) {
        setTimeout(() => {
          if (newVal.length == 2) {
            this.list.push({
              content: "好的明白了。您可以告诉我一下您的教学对象吗？",
              type: "bot",
              animationState: true,
            });
          } else if (newVal.length == 4) {
            this.list.push({
              content: "收到。您能告诉我你的授课主题吗？",
              type: "bot",
              animationState: true,
            });
          } else if (newVal.length == 6) {
            this.list.push({
              content: "您能为我大致描述一下您的课程目标吗？",
              type: "bot",
              animationState: true,
            });
          } else if (newVal.length == 8) {
            this.list.push({
              content: "您还有其它需要补充的吗？",
              type: "bot",
              animationState: true,
            });
          }
          this.scrollBottom();
          if (newVal.length !== 11) {
            this.simulateRequest().then((res) => {
              this.list[this.list.length - 1].animationState = false;
            });
          }
        }, 1000);
      },
      deep: true,
    },
    offect: {
      handler(newVal, oldVal) {
        this.deferred = true; // 页面背景
        setTimeout(() => {
          this.Delayed = true; // 延时展示(答案预览)
        }, 2000);
      },
    },
  },
};
</script>

<style lang="scss" scoped>
/* 如果你的 el-input type 设置成textarea ，就要用这个了 */
::v-deep .footerBtn .el-textarea__inner {
  border: 0;
  resize: none;
}

::v-deep p {
  margin: 0;
}

.AIdialogue {
  width: 100%;
  min-height: calc(100vh - 84px);
  background: linear-gradient(53deg, #fff 10.67%, #f9edff 54.14%, #81c2ff);
  background-size: 100%;
  filter: blur(92px);
  opacity: 0;
  position: absolute;
  transition: opacity 2s ease-in-out;
}

.gCbxc5 {
  opacity: 1;
}

.xIlPaF {
  width: 100%;
  min-height: calc(100vh - 84px);
  padding: 20px;
  overflow: hidden;
  position: relative;
  z-index: 99;
  display: flex;
  box-sizing: border-box;
}

.xIlPaF .qfa7zW {
  background: #fff;
  border-radius: 30px;
  box-shadow: 0 12px 50px 26px rgba(0, 0, 0, 0.03);
  box-sizing: border-box;
  flex-grow: 1;
  max-height: calc(var(--100vh) - 40px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  overflow: hidden;

  .wasolt {
    width: calc(100% - 40px);
    max-width: 590px;

    max-height: calc(100vh - 250px);
    height: calc(100vh - 250px);
    overflow-x: visible;
    overflow-y: scroll;
    padding: 20px 0 120px 0;
    scrollbar-width: none;

    .item {
      border-radius: 20px;
      padding: 21px 24px;

      img {
        width: 20px;
        height: 20px;
      }

      .usable__root {
        width: 30px;
        height: 30px;
        min-width: 30px;
        min-height: 30px;
        border-radius: 50%;
        overflow: hidden;
        margin-right: 10px;

        img {
          width: 30px;
          height: 30px;
        }
      }

      span {
        word-wrap: break-word;
      }
    }

    .MDCzlq {
      display: flex;
      align-items: flex-start;
    }

    .X05sUq {
      background: #f8f8fa;
      display: flex;
      align-items: flex-start;
    }
  }
}

.xIlPaF .qfa7zW .g6rrRa {
  width: 100%;
  align-items: center;
  box-sizing: border-box;
  height: 28px;
  justify-content: space-between;
  // padding: 20px 40px 20px 34px;
  z-index: 100;
}

.xIlPaF .qfa7zW .footerBtn {
  width: calc(100% - 40px);
  max-width: 590px;
  background: linear-gradient(#fff, #fff) padding-box,
    linear-gradient(266.44deg, #5ff2cf -28.21%, #0e53fd) border-box;
  border: 1px solid transparent !important;
  border-radius: 20px !important;
  box-shadow: none !important;
  padding: 14px 60px 14px 24px !important;
  box-sizing: border-box;
  position: relative;
}

.xIlPaF .qfa7zW .footerBtn .Mrwb3p {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

.xIlPaF .qfa7zW .gAF9KM {
  background: linear-gradient(#fff, #fff) padding-box,
    linear-gradient(52.63deg,
      hsla(0, 0%, 87%, 0.8) 18.28%,
      hsla(0, 0%, 87%, 0.8) 51.81%,
      hsla(0, 0%, 87%, 0.8) 87.19%),
    linear-gradient(0deg, hsla(0, 0%, 87%, 0.3), hsla(0, 0%, 87%, 0.3)) border-box;
}

.xIlPaF .qfa7zW .sendBox {
  position: absolute;
  right: 8px;
  transition: opacity 0.2s ease-in-out !important;
  width: 40px !important;
  height: 40px !important;
  background: linear-gradient(266.44deg, #5ff2cf -28.21%, #0e53fd);
  border: none !important;
  border-radius: 15px !important;
  bottom: 7px;
  cursor: pointer;

  img {
    width: 20px;
    height: 20px;
  }
}

.xIlPaF .qfa7zW .IqKDO6 {
  opacity: 0.4;
}

.xIlPaF .qfa7zW .FtoDFp {
  background: hsla(0, 0%, 87%, 0.8);
}

// 答案预览
.xIlPaF .w0Ne1v {
  opacity: 0;
  transition: 1s 1s padding, 1s opacity, 2s width ease-in-out;
  width: 0%;
  backdrop-filter: blur(20px);
  background: hsla(0, 0%, 100%, 0.35);
  border-radius: 30px;
  box-shadow: 0 12px 50px 26px rgba(0, 0, 0, 0.03);
  box-sizing: border-box;
  height: calc(var(--100vh) - 40px);
  margin-left: 20px;
  overflow: hidden;
  padding: 0;

  .cnpA9f {
    color: #3d49b8 !important;
    line-height: 1.4;
    margin: 0 0 24px 0;
    font-size: 14px;
    opacity: 0;
    transition: filter 1s ease, opacity 1s ease, height 1s ease !important;
  }

  .g5WTUf {
    opacity: 0;
    color: #3d49b8 !important;
    font-size: 24px !important;
    font-style: normal !important;
    font-weight: 700 !important;
    height: auto !important;
    line-height: 1.3 !important;
    text-transform: capitalize !important;
    transition: filter 1s ease, opacity 1s ease, height 1s ease !important;
  }

  .yy15WF {
    opacity: 1;
  }
}

.xIlPaF .ssB8rM {
  opacity: 1;
  width: 25%;
  padding: 46px 48px;
  overflow: auto;
}

.xIlPaF .w0Ne1v .iJQbS0 {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-top: 24px;

  .lWRWg1 {
    margin: 0;
    color: #3d49b8 !important;
    font-size: 16px !important;
    font-style: normal !important;
    height: auto !important;
    line-height: 1.3 !important;
    transition: filter 1s ease, opacity 1s ease, height 1s ease !important;
  }

  hr {
    background: linear-gradient(90deg,
        rgba(61, 73, 184, 0.2) 4.76%,
        rgba(61, 73, 184, 0));
    border: none;
    height: 1px;
    margin: 0;
    padding: 0;
    position: relative;
    width: 100%;
  }
}

.xIlPaF .w0Ne1v .TFPFEa {
  background: transparent !important;
  box-sizing: border-box;
  margin-left: calc(50% - 60px) !important;
  margin-top: 5px !important;
  transition: filter 1s ease-in, opacity 1s ease-in;
}

.xIlPaF .w0Ne1v .h_Yv_y {
  filter: blur(12px);
  opacity: 0;
}

// 动画效果 (由下向上)
.animation_fadeInUp {
  animation: fadeInUp;
  animation-duration: 1s; // 时间
  animation-iteration-count: 1; // 此行次数
}

// 动画效果 (由下向上)
.animation_fadeInBottom {
  animation: fadeInDown;
  animation-duration: 1s; // 时间
  animation-iteration-count: 1; // 此行次数
}

// 动画效果 淡入
.animation_fadeInnDown {
  opacity: 0;
  // animation: fadeIn;
  // animation-duration: 2s; // 时间
  // animation-iteration-count: 1; // 此行次数
}

.wds_1_104_2_ButtonCore__root {
  align-items: center;
  cursor: pointer;
  display: inline-flex;
}

.tnnsET {
  background-size: 100% 100% !important;
  transition: background-size 0.3s ease;
  margin-top: 10px;
  border-radius: 15px;
  background: linear-gradient(266.44deg, #5ff2cf -28.21%, #0e53fd) !important;
  border: 0 !important;
  outline-color: transparent !important;
  padding: 6px 18px;

  span {
    color: #fff;
    transition: all 0.3s ease-in-out;
    white-space: normal;
    font-size: 14px;
    font-weight: 500;
  }
}
</style>
